package com.gzhryc.socket.netty;

import com.gzhryc.socket.SocketCallback;
import com.gzhryc.socket.SocketEvent;
import com.gzhryc.socket.SocketMessage;
import com.gzhryc.socket.SocketNode;
import com.gzhryc.socket.message.ByteSocketMessage;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ByteNettyChannelHandler extends ChannelInboundHandlerAdapter {

	final protected SocketNode mNode;
	final protected SocketCallback mCallback;

	public ByteNettyChannelHandler(SocketNode mNode, SocketCallback callback) {
		this.mNode = mNode;
		this.mCallback = callback;
	}

	public void channelRegistered(ChannelHandlerContext ctx) throws Exception {}

	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		byte[] bytes = null;
		if (ByteBuf.class.isInstance(msg)) {
			ByteBuf buffer = ByteBuf.class.cast(msg);
			bytes = buffer.array();
		} else {
			bytes = (byte[]) msg;
		}
		final SocketMessage byteMsg = new ByteSocketMessage(bytes);
		final Channel channel = ctx.channel();
		mNode.runTask(new Runnable() {
			public void run() {
				SocketEvent event = new SocketEvent(new ChannelSocketNode(channel),byteMsg);
				mCallback.messageArrived(event);
			}
		});
	}

	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		final Channel channel = ctx.channel();
		mNode.runTask(new Runnable() {
			public void run() {
				SocketEvent event = new SocketEvent(new ChannelSocketNode(channel));
				mCallback.connectionLost(event);
			}
		});
	}

	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		final Channel channel = ctx.channel();
		mNode.runTask(new Runnable() {
			public void run() {
				SocketEvent event = new SocketEvent(new ChannelSocketNode(channel));
				mCallback.connected(event);
			}
		});
	}
}
